#include <jni.h>
#include <apr_pools.h>
#include "svn_error.h"
#include "svn_string.h"

jstring
make_jstring(JNIEnv *env, const char *c);

jstring
make_jstring2(JNIEnv *env, const svn_string_t *str);

jbyteArray
make_jbyteArray(JNIEnv *env, const svn_string_t *str);

char *
make_cstring(JNIEnv *env, jstring jstr, apr_pool_t *pool);

svn_string_t *
make_cstring2(JNIEnv *env, jstring jstr, apr_pool_t *pool);

void
throw_exception(JNIEnv *env, const char *cname, const char *msg);

/* convert svn error into java exception */
void
throw_svn_exception(JNIEnv *env, svn_error_t *err, svn_boolean_t clear_existing);
/* svn error code for use when a callback into java has raised
 * an exception.  This must be outside the range of reserved APR
 * errors and also outside the range of reserved SVN errors.
 */
#define SVNJ_ERROR_START (SVN_ERR_MALFUNC_CATEGORY_START + SVN_ERR_CATEGORY_SIZE)

/* a java exception has been raised.
 * return a corresponding svn error
 * to unwind C stack and get back to java
 */
svn_error_t *
exception_to_svn_err(JNIEnv *env);

/* translate java exception -> svn err */
#define SVNJ_JAVA_CHECK() do { return exception_to_svn_err(env); } while (0)

/* translate svn error -> java exception */
#define SVN_JNI_ERR(expr, ret_val)                      \
  do {                                                  \
    svn_error_t *svn_jni_err__temp = (expr);            \
    if (svn_jni_err__temp != SVN_NO_ERROR) {            \
    throw_svn_exception(env, svn_jni_err__temp, FALSE); \
      return ret_val ;                                  \
    }                                                   \
  } while (0)

/* is a java exception pending? */
#define IS_JAVA_EXCEPTION() ((*env)->ExceptionCheck(env))

/* make sure C pointer not null */
#define CHECK_PTR(PTR,RET)                                                  \
  do                                                                        \
    {                                                                       \
      if (!(PTR))                                                           \
        {                                                                   \
          throw_exception(env, "java/lang/RuntimeException",                \
                          "context closed");                                \
          return RET;                                                       \
        }                                                                   \
    }                                                                       \
  while (0)

/* base svnj package */
#define SVNJPKG "com/googlecode/svnj"
/* base tigris package */
#define TIGRISPKG "org/tigris/subversion/javahl"

/*jstring
assemble_error_message(JNIEnv *env, svn_error_t *err, apr_pool_t *pool);
*/
